package gframework.bean.consulta;

import gframework.bean.Conexao;
import gframework.bean.Util;
import gframework.bean.combo.GComboBox;
import gframework.bean.panel.GPanel;
import gframework.bean.table.GColumnTable;
import gframework.bean.table.GTable;
import gframework.bean.textField.GTextField;
import java.awt.Color;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.sql.ResultSet;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;

public class Consulta extends GPanel {

    public static final int BOOLEAN = 1;
    public static final int DOUBLE = 2;
    public static final int INT = 3;
    public static final int DATA = 4;
    public static final int LONG = 5;
    public static final int STRING = 6;
    private String campoId = "id";
    private String campoDescricao = "descricao";
    private String tabela = "";
    private String filtro = "";
    private String complemento = "";
    private Vector<ConsultaRetorno> retorno = new Vector();
    private int columns = 0;
    private boolean consultaDescricao = false;
    private GTable tblConsulta = new GTable();

    public void addEventoConsultaCampoListener(EventoConsultaListener listener) {
        listenerList.add(EventoConsultaListener.class, listener);
    }

    public void removeEventoConsultaCampoListener(EventoConsultaListener listener) {
        listenerList.remove(EventoConsultaListener.class, listener);
    }

    void fireEventoAbreTelaConsulta(EventoConsulta evt) {
        Object[] listeners = listenerList.getListenerList();

        for (int i = 0; i < listeners.length; i += 2) {
            if (listeners[i] == EventoConsultaListener.class) {
                ((EventoConsultaListener) listeners[i + 1]).abreTelaConsulta(evt);
            }
        }
    }

    void fireEventoAposConsulta(EventoConsulta evt) {
        Object[] listeners = listenerList.getListenerList();

        for (int i = 0; i < listeners.length; i += 2) {
            if (listeners[i] == EventoConsultaListener.class) {
                ((EventoConsultaListener) listeners[i + 1]).aposConsulta(evt);
            }
        }
    }

    public Consulta() {
        initComponents();
        
        popConsulta.add(tblConsulta);

    }

    @Override
    public void requestFocus() {
        txtCodigo.requestFocus();
    }

    public void consultar() throws Exception {
        consultar(false);
    }

    public void consultar(boolean i_eventoAposConsulta) throws Exception {
        Statement stm = null;
        ResultSet rst = null;
        StringBuffer sql = null;

        stm = Conexao.createStatement();

        sql = new StringBuffer();
        sql.append("SELECT " + tabela + "." + campoDescricao + " AS descricao");

        for (ConsultaRetorno oRetorno : retorno) {
            sql.append(", " + oRetorno.nome + " AS " + oRetorno.alias);
        }

        sql.append(" FROM " + tabela);
        sql.append(" " + getComplemento());

        if (txtCodigo.getText().length() == 13) {
            sql.append(" WHERE " + tabela + ".automacao = " + txtCodigo.getText());

        } else {
            sql.append(" WHERE " + tabela + "." + campoId + " = " + txtCodigo.getText());

        }

        if (!filtro.equals("")) {
            sql.append(filtro);
        }

        rst = stm.executeQuery(sql.toString());

        if (!rst.next()) {
            //txtDescricao.setText("");
            limparRetorno();

            throw new Exception(Util.MSG_REGISTRO_NAO_ENCONTRADO);
        }

        if (txtCodigo.getText().length() == 13) {
            txtCodigo.setText(Util.formatNumber(txtCodigo.getInt(), 6));
        } else {
            if (getColumns() > 0) {
                txtCodigo.setText(Util.formatNumber(txtCodigo.getInt(), getColumns()));
            }
        }

        //txtDescricao.setText(rst.getString("descricao"));

        for (ConsultaRetorno oRetorno : retorno) {
            if (oRetorno.campo instanceof GComboBox) {
                GComboBox cboCampo = (GComboBox) oRetorno.campo;
                cboCampo.setId(rst.getInt(oRetorno.alias));

            } else if (oRetorno.campo instanceof GTextField) {
                GTextField txtCampo = (GTextField) oRetorno.campo;

                if (oRetorno.tipo == DOUBLE) {
                    txtCampo.setDouble(rst.getDouble(oRetorno.alias));
                } else {
                    txtCampo.setText(rst.getString(oRetorno.alias));
                }

            } else {
                if (oRetorno.tipo == BOOLEAN) {
                    oRetorno.campo = rst.getBoolean(oRetorno.alias);
                } else if (oRetorno.tipo == DOUBLE) {
                    oRetorno.campo = rst.getDouble(oRetorno.alias);
                } else if (oRetorno.tipo == INT) {
                    oRetorno.campo = rst.getInt(oRetorno.alias);
                } else if (oRetorno.tipo == STRING) {
                    oRetorno.campo = rst.getString(oRetorno.alias);
                } else if (oRetorno.tipo == DATA) {
                    oRetorno.campo = rst.getDate(oRetorno.alias);
                } else if (oRetorno.tipo == LONG) {
                    oRetorno.campo = rst.getLong(oRetorno.alias);
                } else {
                    oRetorno.campo = rst.getString(oRetorno.alias);
                }
            }
        }

        stm.close();

        if (i_eventoAposConsulta) {
            fireEventoAposConsulta(new EventoConsulta(this));
        }
    }

    public void addComplemento(String i_script) throws Exception {
        this.complemento += " " + i_script;
    }

    public void addRetorno(Object i_campo, String i_nome, int i_tipo, String i_alias) throws Exception {
        ConsultaRetorno oRetorno = new ConsultaRetorno();
        oRetorno.campo = i_campo;
        oRetorno.nome = i_nome;
        oRetorno.tipo = i_tipo;
        oRetorno.alias = i_alias;

        this.retorno.add(oRetorno);
    }

    /**
     * adiciona retorno ao consulta campo(direto no campo de destino c/ tipo de
     * dado)
     *
     * @param i_campo campo de destino do retorno
     * @param i_nome nome do campo na tabela
     * @param i_tipo tipo de dado do campo
     * @throws java.lang.Exception
     */
    public void addRetorno(Object i_campo, String i_nome, int i_tipo) throws Exception {
        addRetorno(i_campo, i_nome, i_tipo, i_nome);
    }

    /**
     * adiciona retorno ao consulta campo (direto no campo de destino)
     *
     * @param i_campo campo de destino do retorno
     * @param i_nome nome do campo na tabela
     * @throws java.lang.Exception
     */
    public void addRetorno(Object i_campo, String i_nome) throws Exception {
        addRetorno(i_campo, i_nome, 0, i_nome);
    }

    /**
     * adiciona retorno ao consulta campo (direto no campo de destino c/ alias)
     *
     * @param i_campo campo de destino do retorno
     * @param i_nome nome do campo na tabela
     * @param i_alias alias para consulta sql
     * @throws java.lang.Exception
     */
    public void addRetorno(Object i_campo, String i_nome, String i_alias) throws Exception {
        addRetorno(i_campo, i_nome, 0, i_alias);
    }

    /**
     * adiciona retorno ao consulta campo ()
     *
     * @param i_nome nome do campo na tabela
     * @param i_tipo tipo de dado do campo
     * @throws java.lang.Exception
     */
    public void addRetorno(String i_nome, int i_tipo) throws Exception {
        addRetorno(null, i_nome, i_tipo, i_nome);
    }

    /**
     * adiciona um retorno ao consulta campo (c/ alias)
     *
     * @param i_nome nome do campo na tabela
     * @param i_tipo tipo de dado do campo
     * @param i_alias alias para a consulta sql
     * @throws java.lang.Exception
     */
    public void addRetorno(String i_nome, int i_tipo, String i_alias) throws Exception {
        addRetorno(null, i_nome, i_tipo, i_alias);
    }

    public boolean getBoolean(String i_nome) throws Exception {
        Boolean valor = (Boolean) getRetorno(i_nome);
        return valor.booleanValue();
    }

    public double getDouble(String i_nome) throws Exception {
        Double valor = (Double) getRetorno(i_nome);
        return valor.doubleValue();
    }

    public int getInt(String i_nome) throws Exception {
        Integer valor = (Integer) getRetorno(i_nome);
        return valor.intValue();
    }

    public String getString(String i_nome) throws Exception {
        String valor = (String) getRetorno(i_nome);
        return valor.toString();
    }

    public String getData(String i_data) throws Exception {
        if (getRetorno(i_data) == null) {
            return "";
        } else {
            return new SimpleDateFormat("dd/MM/yyyy").format(getRetorno(i_data));
        }
    }

    private Object getRetorno(String i_nome) throws Exception {
        for (ConsultaRetorno oRetorno : retorno) {
            if (oRetorno.nome.equals(i_nome) || oRetorno.alias.equals(i_nome)) {
                return oRetorno.campo;
            }
        }

        return null;
    }

    private void limparRetorno() throws Exception {
        for (ConsultaRetorno oRetorno : retorno) {
            if (oRetorno.campo instanceof GComboBox) {
                GComboBox cboCampo = (GComboBox) oRetorno.campo;
                cboCampo.setId(-1);

            } else if (oRetorno.campo instanceof GTextField) {
                GTextField txtCampo = (GTextField) oRetorno.campo;
                txtCampo.setText("");

            } else {
                oRetorno.campo = null;
            }
        }
    }

    public void clear() throws Exception {
        txtCodigo.setText("");
        //txtDescricao.setText("");

        limparRetorno();
    }

//    public Vector<AutoCompletarVO> consultaAutoCompletar() throws Exception {
//        Statement stm = null;
//        ResultSet rst = null;
//
//        stm = Conexao.createStatement();
//
//        rst = stm.executeQuery("SELECT " + tabela + "." + campoId + "," + tabela + "." + campoDescricao + " FROM " + tabela + " ORDER BY " + campoDescricao);
//
//        Vector<AutoCompletarVO> vAutoCompletar = new Vector();
//
//        while (rst.next()) {
//            AutoCompletarVO oAutoComplete = new AutoCompletarVO();
//            oAutoComplete.id = rst.getInt(campoId);
//            oAutoComplete.descricao = rst.getString(campoDescricao);
//
//            vAutoCompletar.add(oAutoComplete);
//        }
//
//        stm.close();
//
//        return vAutoCompletar;
//    }

    @Override
    public void transferFocus() {
        txtCodigo.transferFocus();
    }

    @Override
    public synchronized void addFocusListener(FocusListener l) {
        txtCodigo.addFocusListener(l);
    }

    @Override
    public synchronized void addKeyListener(KeyListener l) {
        txtCodigo.addKeyListener(l);
    }

    public void consultarDescricao()throws Exception{
        Statement stm = null;
        ResultSet rst = null;
        StringBuilder sql = null;

        List<ConsultaVO> vConsulta = new ArrayList();

        if (txtCodigo.getText().length() > 0) {
            stm = Conexao.createStatement();
            sql = new StringBuilder();
            sql.append("SELECT " + campoId + " AS id, " + campoDescricao + " AS descricao");
            sql.append(" FROM " + tabela);
            sql.append(" WHERE " + Util.getGoogle(campoDescricao, txtCodigo.getText().toUpperCase()));

            rst = stm.executeQuery(sql.toString());

            int i = 0;
            
            while (rst.next()) {
                if(i >= 20){
                    break;
                }
                
                ConsultaVO oProduto = new ConsultaVO();
                oProduto.id = rst.getInt("id");
                oProduto.descricao = rst.getString("descricao");

                vConsulta.add(oProduto);
                
                i++;
            }

            stm.close();
        }

        GColumnTable[] colunas = new GColumnTable[]{
            new GColumnTable("Código", 70, true, SwingConstants.LEFT, false, null),
            new GColumnTable("Descrição", 280, true, SwingConstants.LEFT, false, null)
        };

        Object[][] dados = new Object[vConsulta.size()][colunas.length];

        int i = 0;

        for (ConsultaVO oConsulta : vConsulta) {
            dados[i][0] = Util.formatNumber(oConsulta.id, 6);
            dados[i][1] = oConsulta.descricao;

            i++;
        }
        
        tblConsulta.setModel(dados, colunas);
        
//        if(vConsulta.size() > 0){
            popConsulta.show(this, txtCodigo.getX(), txtCodigo.getY() + txtCodigo.getHeight());
            popConsulta.setSize(tblConsulta.getWidth(), tblConsulta.getHeight());
//        }else{
//            popConsulta.setVisible(false);
//        }
        
        popConsulta.repaint();
        popConsulta.updateUI();
        
        txtCodigo.requestFocus();
        txtCodigo.setSelectionEnd(txtCodigo.getText().length());
        txtCodigo.setSelectionStart(txtCodigo.getText().length());
        txtCodigo.setCaretPosition(txtCodigo.getText().length());

    }
    
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        popConsulta = new javax.swing.JPopupMenu();
        btnLimpar = new gframework.bean.button.GButton();
        txtCodigo = new gframework.bean.textField.GTextField();

        popConsulta.setBorder(null);

        setBorder(null);
        addHierarchyBoundsListener(new java.awt.event.HierarchyBoundsListener() {
            public void ancestorMoved(java.awt.event.HierarchyEvent evt) {
            }
            public void ancestorResized(java.awt.event.HierarchyEvent evt) {
                formAncestorResized(evt);
            }
        });
        addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                formFocusLost(evt);
            }
        });

        btnLimpar.setBorder(null);
        btnLimpar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/gframework/img/limpar.png"))); // NOI18N
        btnLimpar.setText("");
        btnLimpar.setBorderPainted(false);
        btnLimpar.setFocusable(false);
        btnLimpar.setPreferredSize(new java.awt.Dimension(16, 16));
        btnLimpar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnLimparActionPerformed(evt);
            }
        });

        txtCodigo.setToolTipText("");
        txtCodigo.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                txtCodigoFocusLost(evt);
            }
        });
        txtCodigo.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                txtCodigoKeyReleased(evt);
            }
            public void keyPressed(java.awt.event.KeyEvent evt) {
                txtCodigoKeyPressed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(txtCodigo, javax.swing.GroupLayout.DEFAULT_SIZE, 273, Short.MAX_VALUE)
                .addGap(2, 2, 2)
                .addComponent(btnLimpar, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 0, 0))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
            .addComponent(btnLimpar, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addComponent(txtCodigo, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        );
    }// </editor-fold>//GEN-END:initComponents
    private void btnLimparActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLimparActionPerformed
        try {
            clear();
            fireEventoAbreTelaConsulta(new EventoConsulta(this));

        } catch (Exception ex) {
            Util.exibirMensagemErro(ex.getMessage(), "Consulta");
        }
}//GEN-LAST:event_btnLimparActionPerformed

    private void txtCodigoFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_txtCodigoFocusLost
//        try {
//            if (txtCodigo.getText().equals("")) {
//                Color background = txtCodigo.getBackground();
//                clear();
//                txtCodigo.setBackground(background);
//
//            } else {
//                consultar(true);
//
//                if (columns > 0) {
//                    txtCodigo.setText(Util.formatNumber(txtCodigo.getText(), columns));
//                }
//            }
//
//        } catch (Exception ex) {
//            Util.exibirMensagemErro(ex.getMessage(), "VRConsultaCampo");
//
//            Runnable doFocus = new Runnable() {
//                public void run() {
//                    txtCodigo.requestFocus();
//                }
//            };
//
//            SwingUtilities.invokeLater(doFocus);
//        }
    }//GEN-LAST:event_txtCodigoFocusLost

    private void formFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_formFocusLost
    }//GEN-LAST:event_formFocusLost

    private void txtCodigoKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtCodigoKeyPressed
        
    }//GEN-LAST:event_txtCodigoKeyPressed

    private void txtCodigoKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtCodigoKeyTyped
    }//GEN-LAST:event_txtCodigoKeyTyped

    private void txtCodigoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtCodigoActionPerformed
    }//GEN-LAST:event_txtCodigoActionPerformed

    private void formAncestorResized(java.awt.event.HierarchyEvent evt) {//GEN-FIRST:event_formAncestorResized
    }//GEN-LAST:event_formAncestorResized

    private void txtCodigoKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtCodigoKeyReleased
        try {
            if (!txtCodigo.getText().isEmpty() && evt.getKeyCode() == KeyEvent.VK_ENTER && Util.isNumero(txtCodigo.getText())) {
                consultar();
            } else{
                consultarDescricao();
            }

        } catch (Exception ex) {
            Util.exibirMensagemErro(ex.getMessage(), "Consulta");
        }
    }//GEN-LAST:event_txtCodigoKeyReleased

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private gframework.bean.button.GButton btnLimpar;
    private javax.swing.JPopupMenu popConsulta;
    private gframework.bean.textField.GTextField txtCodigo;
    // End of variables declaration//GEN-END:variables

    public String getCampoId() {
        return campoId;
    }

    public void setCampoId(String campoId) {
        this.campoId = campoId;
    }

    public String getCampoDescricao() {
        return campoDescricao;
    }

    public void setCampoDescricao(String campoDescricao) {
        this.campoDescricao = campoDescricao;
    }

    public String getTabela() {
        return tabela;
    }

    public void setTabela(String tabela) {
        this.tabela = tabela;
    }

    public void setWidth(int tamanho) {
        //txtDescricao.setSize(tamanho, 20);
    }

    public String getFiltro() {
        return filtro;
    }

    public void setFiltro(String filtro) {
        this.filtro = filtro;
    }

    public int getId() throws Exception {
        if (txtCodigo.getText().equals("")) {
            return -1;
        } else {
            return txtCodigo.getInt();
        }
    }

    public String getDescricao() {
        return "";//txtDescricao.getText();
    }

    public void setDescricao(String i_descricao) {
//        txtDescricao.setText(i_descricao);
    }

    public void setId(int i_id) {
        txtCodigo.setText(String.valueOf(i_id));
    }

    /**
     * @deprecated Utilize setId(int)
     * @param i_id
     */
    public void setId(String i_id) {
        setId(Integer.parseInt(i_id));
    }

    public void setCodigoBackground(Color bg) {
        txtCodigo.setBackground(bg);
    }

    public int getColumns() {
        return this.columns;
    }

    public void setColumns(int i_columns) {
        this.columns = i_columns;
        txtCodigo.setColumns(i_columns);
    }

    @Override
    public void setEnabled(boolean i_enable) {
        txtCodigo.setEnabled(i_enable);
        if (consultaDescricao) {
            //txtDescricao.setEnabled(false);
        }
        btnLimpar.setEnabled(i_enable);
    }

    @Override
    public boolean isEnabled() {
        return txtCodigo.isEnabled();
    }

    public String getComplemento() {
        return complemento;
    }

    public void setComplemento(String complemento) {
        this.complemento = complemento;
    }

    public boolean isConsultaDescricao() {
        return consultaDescricao;
    }

    public void setConsultaDescricao(boolean consultaDescricao) {
        this.consultaDescricao = consultaDescricao;

        //txtDescricao.setEditable(consultaDescricao);
        //txtDescricao.setEnabled(consultaDescricao);
    }

    public boolean isTeclaEnter() {
        return txtCodigo.isTeclaEnter();
    }

    public void setTeclaEnter(boolean teclaEnter) {
        txtCodigo.setTeclaEnter(teclaEnter);
    }

    class ConsultaRetorno {

        public Object campo = null;
        public String nome = "";
        public int tipo = 0;
        public String alias = "";
    }

    public class ConsultaVO {

        public int id = 0;
        public String descricao = "";

        @Override
        public String toString() {
            return descricao;
        }
    }
}
